package com.sgj.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.sgj.common.constant.MemberConstant;
import com.sgj.common.utils.HttpUtils;
import com.sgj.common.vo.MemberRegistVo;
import com.sgj.common.vo.SocialUser;
import com.sgj.common.vo.UserLoginVo;
import com.sgj.gulimall.member.dao.MemberLevelDao;
import com.sgj.gulimall.member.entity.MemberLevelEntity;
import com.sgj.gulimall.member.exception.PhoneExistException;
import com.sgj.gulimall.member.exception.UserNameExistException;
import com.sgj.gulimall.member.vo.SocialUserDetails;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sgj.common.utils.PageUtils;
import com.sgj.common.utils.Query;

import com.sgj.gulimall.member.dao.MemberDao;
import com.sgj.gulimall.member.entity.MemberEntity;
import com.sgj.gulimall.member.service.MemberService;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    private MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public MemberEntity oAuthLogin(SocialUser socialUser) throws Exception {
        // 获取用户id
        Map<String, String> map = new HashMap<>();
        map.put("access_token", socialUser.getAccess_token());
        HttpResponse response = HttpUtils.doGet("https://gitee.com", "/api/v5/user", "get", new HashMap<>(), map);
        if (response.getStatusLine().getStatusCode() == 200) {
            String json = EntityUtils.toString(response.getEntity());
            SocialUserDetails socialUserDetails = JSON.parseObject(json, SocialUserDetails.class);
            // 登陆与注册逻辑合并
            MemberEntity entity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", socialUserDetails.getId()));
            if (Objects.nonNull(entity)) {
                // 该用户已注册
                MemberEntity member = MemberEntity.builder()
                        .id(entity.getId())
                        .accessToken(socialUser.getAccess_token())
                        .expiresIn(socialUser.getExpires_in())
                        .refreshToken(socialUser.getRefresh_token())
                        .scope(socialUser.getScope())
                        .build();
                baseMapper.updateById(member);
                entity.setAccessToken(socialUser.getAccess_token());
                entity.setExpiresIn(socialUser.getExpires_in());
                entity.setRefreshToken(socialUser.getRefresh_token());
                entity.setScope(socialUser.getScope());
                return entity;
            } else {
                // 没有查询到对应社交用户，新建用户
                MemberEntity regist = MemberEntity.builder()
                        .username(socialUserDetails.getName())
                        .nickname(socialUserDetails.getName())
                        .header(socialUserDetails.getAvatar_url())
                        .email(socialUserDetails.getEmail())
                        .gender(1)
                        .integration(0)
                        .growth(0)
                        .status(1)
                        .socialUid(socialUserDetails.getId())
                        .accessToken(socialUser.getAccess_token())
                        .expiresIn(socialUser.getExpires_in())
                        .refreshToken(socialUser.getRefresh_token())
                        .scope(socialUser.getScope())
                        .createTime(new Date())
                        .build();
                baseMapper.insert(regist);
                return regist;
            }
        }
        return null;
    }

    @Override
    public MemberEntity login(UserLoginVo vo) {
        // 去数据库校验账号密码是否正确
        MemberEntity entity = baseMapper.selectOne(
                new QueryWrapper<MemberEntity>()
                        .eq("username", vo.getLoginAccount())
                        .or()
                        .eq("mobile", vo.getLoginAccount())
                        .or()
                        .eq("email", vo.getLoginAccount())
        );
        if (Objects.isNull(entity)) {
            // 登陆失败
            return null;
        }
        // 密码校验
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(vo.getPassword(), entity.getPassword());
        if (matches) {
            // 登陆成功
            return entity;
        }
        return null;
    }

    @Override
    public void register(MemberRegistVo vo) {
        // 获取默认等级
        MemberLevelEntity levelEntity = memberLevelDao.getDefaultLevel();
        // 校验用户名与手机号是否重复
        checkUserNameUnique(vo.getUserName());
        checkPhoneUnique(vo.getPhone());
        // 加密密码
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(vo.getPassword());

        MemberEntity entity = MemberEntity.builder()
                .levelId(levelEntity.getId())
                .username(vo.getUserName())
                .nickname(vo.getUserName())
                .password(encode)
                .mobile(vo.getPhone())
                // 给予用户默认头像
                .header(MemberConstant.DEFAULT_AVATAR)
                .gender(1)
                .integration(0)
                .growth(0)
                .status(1)
                .createTime(new Date())
                .build();
        baseMapper.insert(entity);
    }

    @Override
    public void checkUserNameUnique(String userName) throws UserNameExistException{
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("username", userName));
        if (count > 0) {
            throw new UserNameExistException();
        }
    }

    @Override
    public void checkPhoneUnique(String phone) throws PhoneExistException{
        Integer count = baseMapper.selectCount(new QueryWrapper<MemberEntity>().eq("mobile", phone));
        if (count > 0) {
            throw new PhoneExistException();
        }
    }

}